﻿using System;
using System.Configuration;
using System.Linq;
using System.Web.Security;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.Data.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using BusinessLogic.Model;
using BusinessLogic.StateManagers;
using BusinessLogic;

public partial class MasterPage : System.Web.UI.MasterPage
{
    protected void Page_Load(object sender, EventArgs e)
    {
        #region AuthenticatedUsers

        if (Request.IsAuthenticated)
        {
            HyperLink hlEditProfile = LoginView1.FindControl("hlEditProfile") as HyperLink;
            hlEditProfile.NavigateUrl =
                "~/Private/EditProfile.aspx?" + QueryStringConstants.Username
                + "=" + Page.User.Identity.Name;

            if (Roles.IsUserInRole(Constants.Roles.Admin))
            {
                pnlAdministartion.Visible = true;
            }
        }

        #endregion

        #region QueryStringURLs

        hlEnglish.NavigateUrl = "~/Main.aspx?" + QueryStringConstants.Tag + "=english";
        hlBulgarian.NavigateUrl = "~/Main.aspx?" + QueryStringConstants.Tag + "=bulgarian";
        hlEnFeeds.NavigateUrl = "~/RSS.aspx?" + QueryStringConstants.Tag + "=english";
        hlBgFeeds.NavigateUrl = "~/RSS.aspx?" + QueryStringConstants.Tag + "=bulgarian";
        linkEnFeeds.Href = "~/RSS.aspx?" + QueryStringConstants.Tag + "=english";
        linkBgFeeds.Href = "~/RSS.aspx?" + QueryStringConstants.Tag + "=bulgarian";

        #endregion

        #region Tags

        List<string> tagValues;

        if (Cache[Constants.Cache.Tags] == null)
        {
            using (BlogNETDataContext dc = new BlogNETDataContext(ConfigurationManager.ConnectionStrings["BlogNETDB"].ConnectionString))
            {
                var tags = from tag in dc.Tags
                           where tag.TagValue != "english" && tag.TagValue != "bulgarian"
                           group tag by tag.TagValue into g
                           select g.Key;

                tagValues = tags.ToList();
                Cache.Add(
                    Constants.Cache.Tags,
                    tagValues,
                    null,
                    DateTime.Now.AddMinutes(60),
                    System.Web.Caching.Cache.NoSlidingExpiration,
                    System.Web.Caching.CacheItemPriority.Default,
                    null);
            }
        }
        else
        {
            tagValues = (List<string>)Cache[Constants.Cache.Tags];
        }

        //We need the query string tags to be able to check the appropriate checkboxes
        string[] queryStringTags = (Request.QueryString[QueryStringConstants.Tag] ?? "").Split(new[]{'|', ' '});

        foreach (string tag in tagValues)
        {
            phTags.Controls.Add(
                new CheckBox 
                {
                    Checked = queryStringTags.Contains(tag),
                    ID = "chk" + tag
                });
            phTags.Controls.Add(
                new HyperLink
                {
                    NavigateUrl = "~/Main.aspx?" + QueryStringConstants.Tag + "=" + tag,
                    Text = tag,
                    Width = 150
                });
        }

        #endregion

        #region LatestComments

        List<object> latestComments;

        if (CacheManager.LatestComments == null)
        {
            using (BlogNETDataContext dc = new BlogNETDataContext(ConfigurationManager.ConnectionStrings["BlogNETDB"].ConnectionString))
            {
                //avoid lazy loading for comments' NewsItem
                DataLoadOptions dlo = new DataLoadOptions();
                dlo.LoadWith<Comment>(c => c.NewsItem);
                dc.LoadOptions = dlo;

                string commentsPageSize = ApplicationManager.CommentsPageSize;
                int size = String.IsNullOrEmpty(commentsPageSize) ? SettingsDefaults.CommentsPageSize : Convert.ToInt32(commentsPageSize);


                var comments = (from comment in dc.Comments
                                orderby comment.PostDate descending
                                select new
                                {
                                    PageNumber = comment.NewsItem.Comments.Count(c => c.PostDate < comment.PostDate) / size + 1,
                                    Comment = comment
                                }).Take(5);

                //Makes the anonymous type usable on other pages by casting it to object
                //The properties of the anonymous type will be retrieved through data binding.
                latestComments = comments.OfType<object>().ToList();
                CacheManager.LatestComments = latestComments;
            }
        }
        else
        {
            latestComments = CacheManager.LatestComments;
        }

        lvLatestComments.DataSource = latestComments;
        lvLatestComments.DataBind();

        #endregion

        #region Quotes

        List<Quote> quotes;

        if (Cache[Constants.Cache.Quotes] == null)
        {
            using (BlogNETDataContext dc = new BlogNETDataContext(ConfigurationManager.ConnectionStrings["BlogNETDB"].ConnectionString))
            {
                var quotesQuery = from quote in dc.Quotes
                                  select quote;

                quotes = quotesQuery.ToList();

                Cache.Add(
                Constants.Cache.Quotes,
                quotes,
                null,
                System.Web.Caching.Cache.NoAbsoluteExpiration,
                System.Web.Caching.Cache.NoSlidingExpiration,
                System.Web.Caching.CacheItemPriority.High,
                null);
            }
        }
        else
        {
            quotes = (List<Quote>)Cache[Constants.Cache.Quotes];
        }

        if (quotes.Count > 0)
        {
            Random random = new Random();

            int index = random.Next(0, quotes.Count);

            lblQuote.Text = quotes[index].Message;
            lblQuoteAuthor.Text = quotes[index].Author;
        }
        else
        {
            ltRandomQuote.Visible = false;
        }

        #endregion

        #region Slogan

        string slogan = (string)Application[Constants.Application.WebsiteSlogan] ?? "";
        if (!String.IsNullOrEmpty(slogan))
        {
            ltSlogan.Text = slogan;
        }

        #endregion

    }

    #region ControlEvents

    protected void Login1_LoggedIn(object sender, EventArgs e)
    {
        Cache.Remove(Constants.Cache.Users);
    }

    protected void btnFindSelectedTagsAnd_Click(object sender, EventArgs e)
    {
        string url = ConstructUrl("+");
        Response.Redirect(url);
    }

    protected void btnFindSelectedTagsOr_Click(object sender, EventArgs e)
    {
        string url = ConstructUrl("|");
        Response.Redirect(url);
    }

    #endregion

    #region Methods

    private string ConstructUrl(string separator)
    {
        StringBuilder sb = new StringBuilder("~/Main.aspx");

        bool firstTag = true;

        foreach (Control c in phTags.Controls)
        {
            CheckBox chk = c as CheckBox;

            if (chk != null && chk.Checked)
            {
                //the ID of the control is "chk" + tag
                string tag = chk.ID.Substring(3);

                //The first tag needs a special treatment because it needs to add query string arguments
                //What is more it does not need to add a +
                if (firstTag)
                {
                    sb.Append("?" + QueryStringConstants.Tag + "=").Append(tag);
                    firstTag = false;
                }
                else
                {
                    sb.Append(separator).Append(tag);
                }
            }
        }

        return sb.ToString();
    }

    #endregion
}
